from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import json
from datetime import timedelta


class Category(models.Model):
    """
    主分类模型 - 存储商品的顶级分类(如电子产品、服装等)
    作为三级分类结构的第一级
    """
    name = models.CharField(max_length=50)  # 分类名称
    description = models.TextField(blank=True)  # 分类描述，可为空
    image = models.ImageField(upload_to='categories/', blank=True, null=True)  # 分类图片，存储在media/categories/目录
    created_time = models.DateTimeField(auto_now_add=True)  # 创建时间，自动设置为创建对象时的时间
    updated_time = models.DateTimeField(auto_now=True)  # 更新时间，自动设置为保存对象时的时间
    
    def __str__(self):
        return self.name  # 返回分类名称作为对象的字符串表示
    
    class Meta:
        verbose_name = "主分类"
        verbose_name_plural = "主分类"
        ordering = ['id']  # 按id升序排序


class SubCategory(models.Model):
    """
    子分类模型 - 存储商品的二级分类(如电子产品下的手机、电脑等)
    作为三级分类结构的第二级
    """
    # 关联主分类，使用外键，当主分类删除时级联删除子分类
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='subcategories')
    #SubCategory 模型通过 category 字段与 Category 模型建立了外键关系  所以
    name = models.CharField(max_length=50)  # 子分类名称
    description = models.TextField(blank=True)  # 子分类描述，可为空
    image = models.ImageField(upload_to='subcategories/', blank=True, null=True)  # 子分类图片
    created_time = models.DateTimeField(auto_now_add=True)  # 创建时间
    updated_time = models.DateTimeField(auto_now=True)  # 更新时间
    
    def __str__(self):
        # 返回"主分类 - 子分类"格式的字符串表示
        return f"{self.category.name} - {self.name}"
    
    class Meta:
        verbose_name = "子分类"
        verbose_name_plural = "子分类"
        ordering = ['category', 'id']  # 先按主分类排序，再按id排序


class ProductType(models.Model):
    """
    商品类型模型 - 存储商品的三级分类(如手机下的智能手机、功能手机等)
    作为三级分类结构的第三级
    """
    # 关联子分类，使用外键，当子分类删除时级联删除商品类型
    subcategory = models.ForeignKey(SubCategory, on_delete=models.CASCADE, related_name='product_types')
    name = models.CharField(max_length=50)  # 商品类型名称
    description = models.TextField(blank=True)  # 商品类型描述，可为空
    created_time = models.DateTimeField(auto_now_add=True)  # 创建时间
    updated_time = models.DateTimeField(auto_now=True)  # 更新时间
    
    def __str__(self):
        # 返回"子分类 - 商品类型"格式的字符串表示
        return f"{self.subcategory.name} - {self.name}"
    
    class Meta:
        verbose_name = "商品类型"
        verbose_name_plural = "商品类型"
        ordering = ['subcategory', 'id']  # 先按子分类排序，再按id排序


class Product(models.Model):
    """
    商品模型 - 存储具体商品信息
    包含价格、图片、库存等商品基本信息
    """
    # 关联商品类型，使用外键，当商品类型删除时级联删除商品
    product_type = models.ForeignKey(ProductType, on_delete=models.CASCADE, related_name='products')
    name = models.CharField(max_length=100)  # 商品名称
    price = models.DecimalField(max_digits=10, decimal_places=2)  # 当前价格，最多10位数，2位小数
    original_price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)  # 原价，用于计算折扣
    description = models.TextField(null=True, blank=True)  # 商品描述，可为空
    main_image = models.CharField(max_length=255)  # 主图路径，使用CharField存储路径而非ImageField
    detail_images_json = models.TextField(blank=True)  # 详情图片路径列表，以JSON格式存储
    skuid = models.CharField(max_length=50, unique=True)  # 商品唯一标识符，确保唯一性
    store_name = models.CharField(max_length=100)  # 店铺名称
    is_self_operated = models.BooleanField(default=False)  # 是否自营商品
    stock = models.IntegerField(default=0)  # 库存数量
    sales = models.IntegerField(default=0)  # 销量
    STATUS_CHOICES = (
        (0, '下架'),
        (1, '上架'),
    )
    status = models.IntegerField(choices=STATUS_CHOICES, default=1)  # 商品状态：上架或下架
    created_time = models.DateTimeField(auto_now_add=True)  # 创建时间
    updated_time = models.DateTimeField(auto_now=True)  # 更新时间
    
    def __str__(self):
        return self.name  # 返回商品名称作为对象的字符串表示
    
    class Meta:
        verbose_name = "商品"
        verbose_name_plural = "商品"
        ordering = ['-created_time']  # 按创建时间降序排序，最新的商品排在前面
    
    @property
    def get_main_image_url(self):
        """
        获取商品主图的完整URL
        处理不同情况下的图片路径，确保前端能正确显示图片
        """
        if not self.main_image:
            # 如果没有主图，返回默认图片
            return '/static/img/products/default.jpg'
        if self.main_image.startswith(('http://', 'https://')):
            # 如果是完整的URL，直接返回
            return self.main_image
        if self.main_image.startswith('static/'):
            # 如果以static/开头，添加前导斜杠
            return f'/{self.main_image}'
        # 其他情况，假设是相对于products目录的路径
        return f'/static/img/products/{self.main_image}'
    
    @property
    def detail_images(self):
        """
        获取详情图片列表
        将JSON格式的字符串转换为Python列表
        """
        if self.detail_images_json:
            return json.loads(self.detail_images_json)
        return []  # 如果没有详情图片，返回空列表
    
    @detail_images.setter
    def detail_images(self, images_list):
        """
        设置详情图片列表
        将Python列表转换为JSON格式的字符串存储
        """
        self.detail_images_json = json.dumps(images_list)
    
    @property
    def discount_rate(self):
        """
        计算折扣率
        如果有原价且原价大于0，返回折扣百分比，否则返回0
        """
        if self.original_price and self.original_price > 0:
            return round((1 - self.price / self.original_price) * 100)
        return 0
    
    @property
    def is_new(self):
        """
        判断是否是新品
        创建时间在30天内的商品被视为新品
        """
        return timezone.now() - self.created_time <= timedelta(days=30)
    
    @property
    def is_on_sale(self):
        """
        判断是否是促销商品
        有原价且当前价格低于原价的商品被视为促销商品
        """
        return self.original_price and self.price < self.original_price


class Comment(models.Model):
    """
    评价模型 - 存储用户对商品的评价信息
    包含评分、评价内容和图片等
    """
    # 关联用户和商品，使用外键
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')  # 评价用户
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='comments')  # 评价商品
    content = models.TextField()  # 评价内容
    rating = models.IntegerField(choices=[(i, i) for i in range(1, 6)])  # 评分，1-5星
    images_json = models.TextField(blank=True)  # 评价图片路径列表，以JSON格式存储
    created_time = models.DateTimeField(auto_now_add=True)  # 创建时间
    updated_time = models.DateTimeField(auto_now=True)  # 更新时间
    
    def __str__(self):
        # 返回"用户对商品的评价"格式的字符串表示
        return f"{self.user.username}对{self.product.name}的评价"
    
    class Meta:
        verbose_name = "商品评价"
        verbose_name_plural = "商品评价"
        ordering = ['-created_time']  # 按创建时间降序排序，最新的评价排在前面
    
    @property
    def images(self):
        """
        获取评价图片列表
        将JSON格式的字符串转换为Python列表
        """
        if self.images_json:
            return json.loads(self.images_json)
        return []  # 如果没有评价图片，返回空列表
    
    @images.setter
    def images(self, images_list):
        """
        设置评价图片列表
        将Python列表转换为JSON格式的字符串存储
        """
        self.images_json = json.dumps(images_list)


class CartItem(models.Model):
    """
    购物车商品模型 - 存储用户购物车中的商品信息
    包含商品、数量和是否选中等信息
    """
    # 关联用户和商品，使用外键
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='cart_items')  # 购物车所属用户
    product = models.ForeignKey(Product, on_delete=models.CASCADE)  # 购物车中的商品
    quantity = models.PositiveIntegerField(default=1)  # 商品数量，默认为1
    selected = models.BooleanField(default=True)  # 是否选中，用于结算时选择
    created_time = models.DateTimeField(auto_now_add=True)  # 创建时间
    updated_time = models.DateTimeField(auto_now=True)  # 更新时间
    
    def __str__(self):
        # 返回"用户的购物车 - 商品名称"格式的字符串表示
        return f"{self.user.username}的购物车 - {self.product.name}"
    
    class Meta:
        verbose_name = "购物车商品"
        verbose_name_plural = "购物车商品"
        unique_together = ('user', 'product')  # 同一用户同一商品只能有一条记录
        
    @property
    def total_price(self):
        """
        计算商品总价
        商品价格乘以数量
        """
        return self.product.price * self.quantity